<template>
  <div class="player_tool" ref="playerTool">
    <div class="player_container" v-show="!isError">
      <div class="player_item" ref="playerItem">
        <div class="player_box" :ref="`videoRef${videoObject.id}`"></div>
      </div>
    </div>
    <div class="info_container" v-show="!isError">
      <div class="info_item">增益：{{ videoObject.gain || '-' }}</div>
      <div class="info_item">光子数：{{ lastMessage.uv || '-' }}</div>
      <div class="info_item">
        最高温度：{{ lastMessage.temperature || '-' }}
      </div>
    </div>
    <div class="canvas_container" v-if="isLabel && !isError">
      <CanvasTool></CanvasTool>
    </div>
    <div class="video-tips" v-show="isError">
      视频加载失败，点击
      <span class="span-btn" @click="retryLoad">刷新</span>
    </div>
    <audio ref="audioPlayerRef" src="@/assets/alarm.mp3"></audio>
  </div>
</template>

<script>
import { uploadFile } from '@/api/camera';
import CanvasTool from '@/components/CanvasTool';
import html2canvas from 'html2canvas';
import _ from 'lodash';
import moment from 'moment';
export default {
  name: 'EasyPlayerPro',
  components: { CanvasTool },
  data() {
    return {
      config: {
        // 是否解析音频
        hasAudio: false,
        // 是否为直播
        isLive: true,
        // 加视频拉伸
        stretch: false,
        // MSE模式
        MSE: false,
        // WCS模式
        WCS: true,
        WASM: true,
        WASMSIMD: true,
        // 加载视频超时
        loadTimeOut: 10,
        loadTimeReplay: 3,
        // 缓冲时间
        bufferTime: 1,
        // 是否开启debug
        debug: false,
      },
      playerInfo: null,
      isLoading: false, // 添加加载状态标志
      playerTimeout: null,
      retryCount: 0, // 当前重试次数
      maxRetries: 3, // 最大重试次数
      isError: false,
    };
  },
  props: {
    videoObject: {
      type: Object,
      default: () => {
        return {
          id: null,
          channelUrl: null,
        };
      },
    },
    isLabel: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    // 配置信息
    appConfig() {
      return this.$store.getters['websocketClient/config'];
    },
    // uv告警值
    uvAlarm() {
      return this.videoObject.irPhotons || null;
    },
    // 温度告警值
    tempAlarm() {
      return this.videoObject.irTemperature || null;
    },
    messages() {
      return this.$store.getters['websocketClient/messages'](
        `${process.env.VUE_APP_WEBSOCKET_URL}/${this.videoObject.cameraId}`
      );
    },
    // 获取最新消息
    lastMessage() {
      const filteredMessages = this.$store.getters['websocketClient/messages'](
        `${process.env.VUE_APP_WEBSOCKET_URL}/${this.videoObject.cameraId}`
      )
        .map((item) => JSON.parse(item))
        .filter(
          (message) =>
            message.cameraId === this.videoObject.cameraId &&
            message.command ===
              this.appConfig['btnCommand']['temperatureAnduvData']
        );
      return (
        filteredMessages[filteredMessages.length - 1]?.data || {
          uv: null,
          temperature: null,
        }
      );
    },
  },
  mounted() {
    this.playCreate();
    this.createWebSocket(this.videoObject.cameraId);
  },
  beforeDestroy() {
    if (this.playerTimeout) {
      clearTimeout(this.playerTimeout);
      this.playerTimeout = null;
    }
    this.playerInfo && this.playerInfo.destroy();
    this.playerInfo = null;
    // this.destroyWebSocket(this.videoObject.cameraId);
  },
  watch: {
    c: {
      handler(newValue, oldValue) {
        if (newValue.id !== oldValue.id) {
          this.$nextTick(() => {
            this.playerInfo && this.playerInfo.destroy();
            setTimeout(() => {
              this.playCreate();
            }, 0);
          });
        }
      },
      deep: true,
    },
    messages: {
      handler(newValue, oldValue) {
        if (newValue && !_.isEqual(newValue, oldValue)) {
          this.$nextTick(() => {
            this.handleAlarm(this.lastMessage);
          });
        }
      },
      deep: true,
    },
  },
  methods: {
    /**
     * 模式切换
     */
    switchDecodingMode() {
      if (this.config.MSE) {
        this.config.MSE = false;
        this.config.WCS = true;
      } else if (this.config.WCS) {
        this.config.WCS = false;
        this.config.WASM = true;
        // this.config.WASMSIMD = true;
      } else if (this.config.WASM && !this.config.WASMSIMD) {
        this.config.WASMSIMD = true;
      } else {
        // 已经尝试了所有模式，无法继续切换
        console.error('All decoding modes have been tried.');
      }
    },
    /**
     * 播放
     */
    onPlayer() {
      this.isLoading = true;
      this.playerTimeout = setTimeout(() => {
        this.playerInfo &&
          this.playerInfo
            .play(this.videoObject.channelUrl)
            .then(() => {
              this.isLoading = false;
            })
            .catch((e) => {
              console.error(e);
              if (e === 'play protocol is fetch, demuxType is null') {
                return;
              }
              this.handleError('播放异常: ' + e);
              this.isLoading = false;
            });
      }, 100);
    },

    /**
     * 创建播放器
     */
    playCreate() {
      const container = this.$refs[`videoRef${this.videoObject.id}`];
      if (!container) {
        console.error(new Error('Container not found'));
        return;
      }
      const easyplayer = new window.EasyPlayerPro(container, {
        isLive: this.config.isLive,
        bufferTime: this.config.bufferTime,
        stretch: this.config.stretch,
        MSE: this.config.MSE,
        WCS: this.config.WCS,
        WASM: this.config.WASM,
        loadTimeOut: this.config.loadTimeOut,
        loadTimeReplay: this.config.loadTimeReplay,
        hasAudio: this.config.hasAudio,
        debug: this.config.debug,
        playbackForwardMaxRateDecodeIFrame: 1,
        // watermark: {
        //   text: {
        //     content: `增益: ${this.videoObject.gain}`,
        //     color: '#000',
        //     opacity: 1,
        //     fontSize: '16px',
        //   },
        //   right: '10px',
        //   top: '10px',
        // },
      });

      easyplayer.on('error', (type, msg) => {
        // 播放失败，尝试切换解码模式
        // this.switchDecodingMode();
        this.handleError('播放异常: ' + type + msg);
      });

      easyplayer.on('timeout', () => {
        // 刷新重播
        this.retryLoad();
      });

      easyplayer.on('videoInfo', () => {
        // console.log('视频信息', videoInfo);
        // const width = videoInfo.width;
        // const height = videoInfo.height;
        // if (width >= 1920 && height >= 1080) {
        //   // 高分辨率视频，使用 WASMSIMD 模式
        //   this.config.MSE = false;
        //   this.config.WCS = false;
        //   this.config.WASM = true;
        //   this.config.WASMSIMD = true;
        // }
      });

      easyplayer.on('pause', () => {
        this.onPlayer();
      });
      // easyplayer.on("fullscreen", (flag) => {
      //   console.log('is fullscreen', flag);
      // });

      easyplayer.on('screenshot', (url) => {
        console.log('截图1111', url);
      });

      easyplayer.on('recordStart', () => {
        console.log('录像11111');
      });

      easyplayer.on('recordEnd', () => {
        console.log('停止录像11111');
        // 重命名视频文件
      });

      this.playerInfo = easyplayer;
      // console.log('playerInfo', this.playerInfo);
      this.onPlayer();
    },
    handleError(errorMessage) {
      console.error(errorMessage);
      if (this.retryCount < this.maxRetries) {
        this.retryCount++;
        this.retryLoad();
      } else {
        this.isError = true;
      }
    },
    retryLoad() {
      this.isError = false;
      this.onDestroy().then(() => {
        this.playCreate();
        this.onPlayer();
      });
    },
    onDestroy() {
      return new Promise((resolve) => {
        if (this.playerInfo) {
          this.playerInfo.destroy();
          this.playerInfo = null;
        }
        setTimeout(() => {
          resolve();
        }, 100);
      });
    },
    /**
     * 处理截图
     */
    onScreenshot() {
      if (this.playerInfo) {
        const base64 = this.playerInfo.screenshot('test', 'png', 0.5, 'base64');
        const blob = this.base64ToBlob(base64, 'image/png');
        // 在需要保存文件的地方
        const timestamp = moment().format('YYYY-MM-DD HH-mm-ss');
        this.saveBlobAsFile(blob, `${timestamp}.png`);
      }
    },
    /**
     * 处理录像&停止录像
     */
    async onRecord(isRecord) {
      if (isRecord) {
        this.playerInfo && this.playerInfo.startRecord();
      } else {
        const timestamp = moment().format('YYYY-MM-DD HH-mm-ss');
        this.playerInfo &&
          this.playerInfo.stopRecordAndSave('video/mp4', timestamp);

        // const blob = this.base64ToBlob(res.data, 'video/mp4');
        // await this.uploadVideo(res);

        // 视频文件上传至服务器
      }
    },
    base64ToBlob(base64, mimeType) {
      const byteCharacters = atob(base64.split(',')[1]);
      const byteNumbers = new Array(byteCharacters.length);
      for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
      }
      const byteArray = new Uint8Array(byteNumbers);
      return new Blob([byteArray], { type: mimeType });
    },
    saveBlobAsFile(blob, fileName) {
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    },
    /**
     * 处理告警截图
     */
    async onAlertScreenshot(type) {
      if (this.playerInfo && type) {
        let cc = await html2canvas(this.$refs.playerTool);
        let base64 = cc.toDataURL('image/png');
        const blob = this.base64ToBlob(base64, 'image/png');
        // 在需要保存文件的地方
        const timestamp = moment().format('YYYY-MM-DD HH-mm-ss');
        // await this.uploadImage(blob, type);
        this.saveBlobAsFile(blob, `${timestamp}.png`);
      }
    },
    /**
     * 处理告警录像
     */
    onAlertRecord() {
      this.onRecord(true);
      console.log('告警录像');
      setTimeout(() => {
        console.log('告警停止录像');
        this.onRecord(false);
      }, 60 * 1000);
    },
    /**
     * 上传图片文件
     */
    async uploadImage(blob, type) {
      const timestamp = moment().format('YYYY-MM-DD HH-mm-ss');
      const formData = new FormData();
      formData.append('file', blob, `${timestamp}.png`);
      formData.append('camera_id', this.videoObject.id);
      formData.append('type', type);
      const res = await uploadFile(formData);
      if (res.code === 200) {
        this.$message.success('截图成功');
      } else {
        this.$message.error('截图失败');
      }
    },
    /**
     * 上传视频文件
     */
    async uploadVideo(blob) {
      const timestamp = moment().format('YYYY-MM-DD HH-mm-ss');
      const formData = new FormData();
      formData.append('file', blob, `${timestamp}.mp4`);
      formData.append('type', '2');
      formData.append('camera_id', this.videoObject.id);
      try {
        const res = await uploadFile(formData);
        if (res.code === 200) {
          this.$message.success('视频上传成功');
        } else {
          this.$message.error('视频上传失败');
        }
      } catch (error) {
        console.error('视频上传失败:', error);
        this.$message.error('视频上传失败');
      }
    },
    /**
     * 新建websocket连接
     */
    createWebSocket(cameraId) {
      this.$store.dispatch(
        'websocketClient/connect',
        `${process.env.VUE_APP_WEBSOCKET_URL}/${cameraId}`
      );
    },

    /**
     * 销毁websocket连接
     */
    destroyWebSocket(cameraId) {
      this.$store.dispatch(
        'websocketClient/close',
        `${process.env.VUE_APP_WEBSOCKET_URL}/${cameraId}`
      );
    },
    /**
     * 播放音频
     */
    playAudio() {
      // this.audioPlaying = true;
      this.$nextTick(() => {
        const audioPlayer = this.$refs.audioPlayerRef;
        if (audioPlayer) {
          audioPlayer
            .play()
            .then(() => {
              console.log('音频播放成功');
            })
            .catch((error) => {
              console.error('音频播放失败', error);
            })
            .finally(() => {
              // this.audioPlaying = false;
            });
        }
      });
    },
    stopAudio() {
      // this.audioPlaying = false;
      this.$nextTick(() => {
        const audioPlayer = this.$refs.audioPlayerRef;
        if (audioPlayer) {
          audioPlayer.pause();
          audioPlayer.currentTime = 0; // 重置音频时间
        }
      });
    },
    /**
     * 处理报警触发
     */
    handleAlarm(message) {
      if (this.tempAlarm === null && this.uvAlarm === null) {
        return;
      }
      if (message.temperature === null && message.uv === null) {
        return;
      }
      if (
        this.tempAlarm !== null &&
        this.uvAlarm !== null &&
        Number(message.temperature) > Number(this.tempAlarm) &&
        Number(message.uv) > Number(this.uvAlarm)
      ) {
        this.$message.error(
          `摄像机${this.videoObject.channelName}的uv告警值：${message.uv}，温度告警值：${message.temperature}`
        );
        this.onAlertScreenshot(3);
        // 录像一分钟
        this.onAlertRecord();
        // 播放音频
        return this.playAudio();
      } else if (
        this.uvAlarm !== null &&
        Number(message.uv) > Number(this.uvAlarm)
      ) {
        this.$message.error(
          `摄像机${this.videoObject.channelName}的uv告警值：${message.uv}`
        );
        this.onAlertScreenshot(3);
        // 录像一分钟
        this.onAlertRecord();
        // 播放音频
        return this.playAudio();
      } else if (
        this.tempAlarm !== null &&
        Number(message.temperature) > Number(this.tempAlarm)
      ) {
        this.$message.error(
          `摄像机${this.videoObject.channelName}的温度告警值：${message.temperature}`
        );
        this.onAlertScreenshot(3);
        // 录像一分钟
        this.onAlertRecord();
        // 播放音频
        return this.playAudio();
      }
    },
  },
};
</script>

<style scoped lang="scss">
.player_tool {
  position: relative;
}

.player_container {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  object-fit: cover; /* 视频填充方式 */
}
.info_container {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 50%;
  text-align: left;
}

.canvas_container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.info_item {
  font-size: 16px;
  font-weight: bold;
  margin-top: 10px;
  margin-left: 10px;
  color: #000;
}

.player_item {
  position: relative;
  padding-bottom: 56%;
  background-color: #000;
  border: 1px #fff solid;
}

.player_box {
  height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
}

.video-tips {
  width: 100%;
  height: 100%;
  background-color: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 20px;
  font-weight: bold;
}
.span-btn {
  margin-left: 5px;
  color: #409eff;
  text-decoration: underline;
  cursor: pointer;
}

/* 关闭截图和录像 */
::v-deep .easyplayer-recording .easyplayer-recording-stop,
::v-deep .easyplayer-controls-right .easyplayer-controls-item.easyplayer-record,
::v-deep
  .easyplayer-controls-right
  .easyplayer-controls-item.easyplayer-record-stop,
::v-deep
  .easyplayer-controls-right
  .easyplayer-controls-item.easyplayer-screenshot {
  display: none !important;
}
</style>
